package com.liao.badminton.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.liao.badminton.code.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liao.badminton.code.util.NameUtil;
import com.liao.badminton.context.BaseContextHandler;
import com.liao.badminton.dto.ActivityParticipatorDto;
import com.liao.badminton.entity.ActivityParticipator;
import com.liao.badminton.entity.BadmintonGroup;
import com.liao.badminton.entity.UserGroupRef;
import com.liao.badminton.redis.RedisEnum;
import com.liao.badminton.redis.RedisUtil;
import com.liao.badminton.code.util.EntityUtils;
import com.liao.badminton.code.util.CheckUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liao.badminton.entity.ActivityRecord;
import com.liao.badminton.dto.ActivityRecordDto;
import com.liao.badminton.service.ActivityParticipatorService;
import com.liao.badminton.service.BadmintonGroupService;
import com.liao.badminton.service.UserGroupRefService;
import com.liao.badminton.vo.ActivityParticipatorVo;
import com.liao.badminton.vo.ActivityRecordVo;
import com.liao.badminton.mapper.ActivityRecordMapper;
import com.liao.badminton.service.ActivityRecordService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import lombok.extern.log4j.Log4j2;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import static cn.hutool.core.util.ObjectUtil.isEmpty;
import static cn.hutool.core.util.ObjectUtil.isNotEmpty;

/**
 * @author liaocheng
 * @date 2024-11-15
 * description:群发布活动记录表
 */
@Component
@Log4j2
public class ActivityRecordServiceImpl extends ServiceImpl<ActivityRecordMapper, ActivityRecord> implements ActivityRecordService {

    @Resource
    private BadmintonGroupService badmintonGroupService;

    @Resource
    private ActivityParticipatorService activityParticipatorService;

    @Resource
    private UserGroupRefService userGroupRefService;

    /**
     * 新增
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10000, rollbackFor = Exception.class)
    public ResponseRest saveActivityRecord(ActivityRecordDto param) throws ProjectException {
        ActivityRecord activityRecord = param.invertEntity();
        Integer validStatus = param.getValidStatus();
        if (isNotEmpty(validStatus) && validStatus == 1) {
            badmintonGroupService.updateActiveNum(param.getGroupId(), 1); //群组织活动数加1
        } else {
            activityRecord.setValidStatus(0);
        }
        BadmintonGroup one = badmintonGroupService.getOne(new LambdaQueryWrapper<BadmintonGroup>().eq(BadmintonGroup::getId, param.getGroupId()));
        activityRecord.setSiteNum(one.getSiteNum());//场地数一般是：2
        activityRecord.setSitePerPrice(one.getSitePerPrice());//场地单价一般是：100
        activityRecord.setFemaleDiscountPrice(one.getFemaleDiscountPrice());//女生优惠价格
        activityRecord.setBucketBallNum(one.getBucketBallNum());//获取群默认设置
        activityRecord.setBucketPerPrice(one.getBucketPerPrice());
        activityRecord.setTimeLength(one.getTimeLength());
        activityRecord.setCollectType(one.getCollectType());
        activityRecord.setFixedMale(one.getFixedMale());
        activityRecord.setFixedFemale(one.getFixedFemale());
        activityRecord.setExtraFixedCost(one.getExtraFixedCost());
        activityRecord.setExtraPerCost(one.getExtraPerCost());
        if (isEmpty(param.getCreateTime())) { //
            EntityUtils.setCreatAndUpdateInfo(activityRecord);
        } else {
            activityRecord.setCreator(BaseContextHandler.getCurrUserID());
            activityRecord.setUpdateTime(new Date());
        }
        this.save(activityRecord);
        ActivityRecordVo activityRecordVo = ActivityRecordVo.invertToVo(activityRecord);
        parseActivityRecord(activityRecord);
//        activityRecordVo.setActivityParticipatorVos();
        return ResponseRest.suc("saveActivityRecord", true);
    }

    public void parseTxt(String txtContent,Map<String, Integer> nameSexMap,Map<String, String> nameRecordMap,List<String> nameList) {
        String[] boutList;
        if (txtContent.contains("候补")) {
            txtContent = StrUtil.subBefore(txtContent, "候补", false);
        }
        if (txtContent.contains("截止")) {
            txtContent = StrUtil.subBefore(txtContent, "截止", false);
        }

        if (txtContent.contains("\n") || txtContent.contains(";")) {
            boutList = txtContent.contains("\n") ? txtContent.split("\n") : txtContent.split(";");
        } else if (txtContent.contains("\\n")) {
            List<String> split = StrUtil.split(txtContent, "\\n");
            boutList  = split.toArray(new String[split.size()]);
        } else {
            boutList = new String[]{txtContent};
        }
        for (int i = 0; i < boutList.length; i++) {
            String userName = StrUtil.trim(boutList[i]);
            if (StrUtil.isBlank(userName) || !NameUtil.hasOrderIndex(userName)) {
                continue;
            }
            String name = NameUtil.wipeIndex(userName);
            name = NameUtil.wipeRemark(name);
            if (StrUtil.isBlank(name) || nameSexMap.containsKey(name.toLowerCase())) {
                continue;
            }
            if (NameUtil.isFemale(name)) {
                name = NameUtil.wipeSex(name);
                nameSexMap.put(name.toLowerCase(), 0);
            } else {
                nameSexMap.put(name.toLowerCase(), 1);
            }
//            log.info("nameSexMap: " + nameSexMap);
            nameList.add(name);
            nameRecordMap.put(name.toLowerCase(), userName);
        }

    }

    private List<ActivityParticipatorVo> parseActivityRecord(ActivityRecord activityRecord) {
        List<ActivityParticipatorVo> resultList = CollectionUtil.newArrayList();
        Long groupId = activityRecord.getGroupId();
        String txtContent = activityRecord.getTxtContent(); // 开始位置为":+换行，"，结束位置为换行符
        if (ObjectUtil.isEmpty(txtContent)) {
            return resultList;
        }
        Map<String, String> nameRecordMap = new LinkedHashMap<>()        ;//本次活动的所有参赛人员
        Map<String, Integer> nameSexMap = new LinkedHashMap<>()        ;//本次活动的所有参赛人员
        List<String> nameList = new ArrayList<>();
        parseTxt(txtContent, nameSexMap, nameRecordMap,nameList);
        Map<String, Integer> dbNameOrderMap = new HashMap<>();//本次活动的所有参赛人员
        List<String> allParticipators = CollectionUtil.newArrayList(nameList);//本次活动的所有参赛人员
        if (isNotEmpty(allParticipators)) {
            List<UserGroupRef> list = userGroupRefService.list(new LambdaQueryWrapper<UserGroupRef>().eq(UserGroupRef::getGroupId, groupId)
                    .in(UserGroupRef::getUserName, allParticipators));
            List<Long> collect = list.stream().map(UserGroupRef::getId).collect(Collectors.toList());
            if (isNotEmpty(list)) {
//                list.stream().map(userGroupRef -> userGroupRef.getUserName()).collect(Collectors.toList()).forEach(dbName -> {
//                    Iterator<String> iterator = allParticipators.iterator();
//                    while (iterator.hasNext()) {
//                        String next = iterator.next();
//                        if (next.equalsIgnoreCase(dbName)) {
//                            iterator.remove();
//                            break;
//                        }
//                    }
//                });

                list.stream().filter(userGroupRef ->
                {
                    String userName = userGroupRef.getUserName();
                    Boolean r = false;
                    for (String allParticipator : allParticipators) {
//                        log.info(userName + " "+allParticipator+"" + allParticipator.equalsIgnoreCase(userName) + " " + nameSexMap.get(userName.toLowerCase()) + " " + userGroupRef.getSex());
                        if (allParticipator.equalsIgnoreCase(userName) && nameSexMap.get(userName.toLowerCase()).equals(userGroupRef.getSex())) {
                            r=true;
                            dbNameOrderMap.put(userName, nameList.indexOf(allParticipator) + 1);
                        }
                    }
//                    log.info("-------------------"+r);
                    return r;
                }).collect(Collectors.toList()).forEach(userGroupRef -> {
                    Iterator<String> iterator = allParticipators.iterator();
                    while (iterator.hasNext()) {
                        String next = iterator.next();
                        if (next.equalsIgnoreCase(userGroupRef.getUserName())) {
                            iterator.remove();
                            break;
                        }
                    }
                });
            } else {
                list = CollectionUtil.newArrayList();
            }
            List<UserGroupRef> addUGReflist = CollectionUtil.newArrayList();
            if (isNotEmpty(allParticipators)) {
                for (String participator : allParticipators) {
                    UserGroupRef userGroupRef = new UserGroupRef();
                    userGroupRef.setGroupId(groupId);
                    userGroupRef.setUserName(participator);
                    userGroupRef.setActivityNum(1);
                    userGroupRef.setSex(nameSexMap.get(participator.toLowerCase()));
                    EntityUtils.setCreatAndUpdateInfo(userGroupRef);
                    addUGReflist.add(userGroupRef);
                }
                List<UserGroupRef> addList = CollectionUtil.newArrayList();
                if (activityRecord.getValidStatus() == 1) {
                    userGroupRefService.saveBatch(addUGReflist);
                     addList = userGroupRefService.list(new LambdaQueryWrapper<UserGroupRef>().eq(UserGroupRef::getGroupId, groupId)
                            .in(UserGroupRef::getUserName, allParticipators));
                }
                if (isNotEmpty(addList)) {
                    list.addAll(addList);
                } else {
                    list.addAll(addUGReflist);
                }
            }
            List<ActivityParticipator> participatorList = CollectionUtil.newArrayList();

            for (UserGroupRef userGroupRef : list) {
                if (!userGroupRef.getSex().equals(nameSexMap.get(userGroupRef.getUserName().toLowerCase()))) {
                    continue;
                }
                String name = userGroupRef.getUserName();
                Long ugrId = userGroupRef.getId();
                ActivityParticipator participator = new ActivityParticipator();
                participator.setSortNum(nameList.indexOf(name)>0?nameList.indexOf(name)+1:dbNameOrderMap.get(name));
                participator.setActivityId(activityRecord.getId());
                participator.setUserGroupRefId(ugrId);
                participator.setSortNum(nameList.indexOf(name) + 1);
                participator.setTxtContent(nameRecordMap.get(name.toLowerCase()));
                EntityUtils.setCreatAndUpdateInfo(participator);
                participatorList.add(participator);
            }
            if (activityRecord.getValidStatus() !=null && activityRecord.getValidStatus() == 1) {
                if (isNotEmpty(collect)) {
                    userGroupRefService.updateActivityNum(collect, 1);
                }
                activityParticipatorService.saveBatch(participatorList);
            }
            activityRecord.setJoinNum(list.size());
            this.updateById(activityRecord);
        }
//        Collections.sort(resultList, Comparator.comparing(ActivityParticipatorVo::getSortNum));
        return resultList;
    }

    /**
     * 删除
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest deletesActivityRecord(ActivityRecordDto param) throws ProjectException {
        List<ActivityRecord> activityRecords = this.listByIds(param.getDelIds());
        if (CollectionUtil.isEmpty(activityRecords)) {
            return ResponseRest.fail("没有找到对应数据");
        }
        for (ActivityRecord activityRecord : activityRecords) {
            if (activityRecord.getValidStatus() == 1) {
                badmintonGroupService.updateActiveNum(activityRecord.getGroupId(), -1); //群组织活动数减1
                List<Long> ugrIds = activityParticipatorService.list(new LambdaQueryWrapper<ActivityParticipator>()
                                .eq(ActivityParticipator::getActivityId, activityRecord.getId()))
                        .stream().map(ActivityParticipator::getUserGroupRefId).collect(Collectors.toList());
                if (isNotEmpty(ugrIds)) {
                    userGroupRefService.updateActivityNum(ugrIds, -1);
                    activityParticipatorService.remove(new LambdaQueryWrapper<ActivityParticipator>()
                            .eq(ActivityParticipator::getActivityId, activityRecord.getId()));
                }
            }
        }
        boolean bool = this.removeByIds(param.getDelIds());
        if (bool) {

            param.getDelIds().forEach(id -> RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "activityRecord", "id", id));
        }
        return ResponseRest.suc("deletesActivityRecord", true);
    }

    /**
     * 修改:修改状态，费用，内容
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10000, rollbackFor = Exception.class)
    public ResponseRest updateActivityRecord(ActivityRecordDto param) throws ProjectException {

        ActivityRecord paramEntity = param.invertEntity();
        Integer validStatus = paramEntity.getValidStatus();
//         CheckUtil.checkValue(validStatus,new ArrayList<>(Arrays.asList(1,0)),"validStatus");
        EntityUtils.setUpdatedInfo(paramEntity);
        ActivityRecord bd = this.getById(param.getId());
        if (validStatus !=null && validStatus == 1 && bd.getValidStatus() == 0) {
            badmintonGroupService.updateActiveNum(bd.getGroupId(), 1); //群组织活动数加1
        }
        paramEntity.setGroupId(bd.getGroupId());
        //计算就交给前端处理？只存结果
        Integer bool = baseMapper.updateBy(paramEntity);
        if (bool>0) {
            RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "activityRecord", "id", param.getId());
        }
//        ActivityRecordVo activityRecordVo = ActivityRecordVo.invertToVo(paramEntity);
        if (param.getTxtContent() == null){
            paramEntity.setTxtContent(bd.getTxtContent());}
        else {
            parseActivityRecord(paramEntity);
            if (bd.getCollectType()==1) { //初始化的
                List<ActivityParticipatorVo> activityParticipatorVos = activityParticipatorService.findByActivityId(param.getId());
                List<ActivityParticipator> fixeds = new ArrayList<>();
                List<Long> userGId = new ArrayList<>();
                activityParticipatorVos.forEach(activityParticipatorVo -> {
                    ActivityParticipator updateCost = new ActivityParticipator();
                    updateCost.setId(activityParticipatorVo.getId());
                    userGId.add(activityParticipatorVo.getUserGroupRefId());
                    if (activityParticipatorVo.getSex() == 0) {
                        updateCost.setCost(bd.getFixedFemale());
                    }else{
                        updateCost.setCost(bd.getFixedMale());
                    }
                    fixeds.add(updateCost);
                });
                activityParticipatorService.updateBatchById(fixeds);
                userGroupRefService.updateCost(userGId);
            }
        }
        List<ActivityParticipatorDto> activityParticipatorDtos = param.getActivityParticipatorDtos();
        if (isNotEmpty(activityParticipatorDtos)) { //计算好球费  前端传进来，可以改的
            List<ActivityParticipator> collect = activityParticipatorDtos.stream().map(dto -> dto.invertEntity()).collect(Collectors.toList());
            activityParticipatorService.updateBatchById(collect);
            List<Long> userGId = collect.stream().map(ActivityParticipator::getUserGroupRefId).collect(Collectors.toList());//更新消费
            userGroupRefService.updateCost(userGId);

        }
        return ResponseRest.suc("updateActivityRecord", true);
    }


    /**
     * 查询列表
     */
    @Override
    public ResponseRest findActivityRecordByPageParam(PageParam<ActivityRecordDto> pageParam) throws ProjectException {
        CheckUtil.checkValue(pageParam, "pageParam");
        ResponseRest resp = ResponseRest.suc("findActivityRecordByPageParam");
        PageHelper.startPage(pageParam.getCurrent(), pageParam.getSize(), "create_time desc");
        //LambdaQueryWrapper<ActivityRecord> query = new LambdaQueryWrapper<>();
        List<ActivityRecord> list = baseMapper.findByPageParam(pageParam);
        List<ActivityRecordVo> collect = list.stream().parallel().map(entity -> ActivityRecordVo.invertToVo(entity)).collect(Collectors.toList());
        resp.setData(new PageInfo<>(collect));
        return resp;
    }

    /**
     * 查询详情
     */
    @Override
    public ResponseRest findDetail(ActivityRecordDto param) throws ProjectException {
        Object getDate = RedisUtil.toGetDate(RedisEnum.CACHE_TABLE_DATA, "activityRecord", "id", param.getId());
        if (isNotEmpty(getDate)) {
            RedisUtil.toFlushExpire(RedisEnum.CACHE_TABLE_DATA, "activityRecord", "id", param.getId());
            return ResponseRest.suc("findDetail", (ActivityRecordVo) getDate);
        }
        ActivityRecordVo vo = null;
        ActivityRecord db = this.getById(param.getId());
        if (isNotEmpty(db)) {
            vo = ActivityRecordVo.invertToVo(db);
            List<ActivityParticipatorVo> activityParticipatorVos = activityParticipatorService.findByActivityId(param.getId());
            vo.setActivityParticipatorVos(activityParticipatorVos);
            RedisUtil.toSaveRedis(RedisEnum.CACHE_TABLE_DATA, "activityRecord", "id", param.getId(), vo, null);
        }
        return ResponseRest.suc("findDetail", vo);
    }

}
